package org.libarae.communication;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import static java.net.URLDecoder.*;
/**
 * HTTPUtils class contains utility methods and objects 
 * that make handling HTTP Post request easier. These 
 * utilities are only in the context of project libarae,
 * and may not be useful for handling standard messages.
 *   
 * @author Edward Raff
 */
public class HTTPUtils 
{
	/**
	 * Takes an HTTP POST message and returns all passed key value pairs, decoded into strings. 
	 * @param httpPostMessage the full HTTP POST message that was originally passed
	 * @return a map containg the key value pairings. 
	 */
	public static Map<String, String> postParams(String httpPostMessage)
	{
		HashMap<String, String> map = new HashMap<String, String>();
		
		/* 
		 * HTTP Post messages have values transfered in key - value pairs. pairs are sperated by '&'.
		 * Keys are seperated by their values by '='. Keys are on the left hand side. 
		 * Both keys and values use standard URL encoding.
		 * 
		 */
		
		//Trailing newlines can be problematic to parsing and are not uncommon
		httpPostMessage = httpPostMessage.trim();
		
		//Key value pairs are on the last line of the http message
		int startIndex = httpPostMessage.lastIndexOf('\n');
		httpPostMessage = httpPostMessage.substring(startIndex+1);
		
		/**
		 * All key value pairs
		 */
		String[] kvPairs = httpPostMessage.split("&");
		
		for(String kv : kvPairs)
		{
			String[] tmp = kv.split("=");
			try {
				map.put(decode(tmp[0], "UTF-8"), decode(tmp[1], "UTF-8"));
			} catch (UnsupportedEncodingException e) { 
				/*
				 * UTF-8 is the standard url that is supposed to be used for HTTP post messages, 
				 * and has been in java since 1.0. If this error throws, we have bigger issues. 
				 */
				System.err.println("Unantipated encoding error in HTTP POST Decode");
			}
		}
		
		return map;
	}

	/**
	 * Takes an HTTP GET message and returns all passed key value pairs, decoded into strings. 
	 * @param httpGetMessage the full HTTP GET message that was orginally passed
	 * @return a map containing the key value parings
	 */
	public static Map<String, String> getParams(String httpGetMessage)
	{
		HashMap<String, String> map = new HashMap<String, String>();
		
		//Trailing newlines can be problematic to parsing and are not uncommon
		httpGetMessage = httpGetMessage.trim();
		
		//The address after the 'GET' contains all information we need
		int endIndex = httpGetMessage.indexOf("HTTP");
		httpGetMessage = httpGetMessage.substring(3+1, endIndex-1).trim();//'GET ' is 4 spaces over , then remove the HTTP/1.X at the end
		
		//Now use endIndex to chop off the address location off, so that only the passed parameters remain
		endIndex = httpGetMessage.indexOf("?");
		httpGetMessage = httpGetMessage.substring(endIndex+1);
		
		
		/**
		 * All key value pairs
		 */
		String[] kvPairs = httpGetMessage.split("&");
		
		for(String kv : kvPairs)
		{
			String[] tmp = kv.split("=");
			try {
				if(tmp.length == 1)
					map.put(decode(tmp[0], "UTF-8"), "");
				else
					map.put(decode(tmp[0], "UTF-8"), decode(tmp[1], "UTF-8"));
			} catch (UnsupportedEncodingException e) { 
				/*
				 * UTF-8 is the standard url that is supposed to be used for HTTP post messages, 
				 * and has been in java since 1.0. If this error throws, we have bigger issues. 
				 */
				System.err.println("Unantipated encoding error in HTTP POST Decode");
			}
		}
		
		return map;
	}

	/**
	 * Returns the address location of the HTTP message, iregardless of whether 
	 * it was a POST or GET message. <br> If the web adress was 
	 * "http://www.mysite.com/index.html", the returned value would be "/index.html"
	 * @param httpMessage the HTTP message in question
	 * @return the sub page of the address
	 */
	public static String postGetAddress(String httpMessage)
	{
		//The address after the 'GET' contains all information we need
		int endIndex = httpMessage.indexOf("HTTP");
		httpMessage = httpMessage.substring(0, endIndex-1).trim();//remove the HTTP/1.X at the end
		httpMessage = httpMessage.replace("GET ", "").replace("POST ", ""); //just delete both
		
		//'?' marks the added paramaters, if anny were added, '?' needs to be escaped in Jave regexs
		return httpMessage.replaceAll("\\?.*", "");
	
	}

	/**
	 * 
	 * @return a standard header of links for every page for a logged in user
	 */
	public static String HTMLPageHeader(String search)
	{
		return "<html><head><title>Libarae</title><meta name=\"viewport\" content=\"width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0\"/><meta name=\"format-detection\" content=\"telephone=no\"/>"+
		"<style TYPE=\"text/css\"><!-- html,body{margin:0px;padding:0px;} .top_bar{width=100%;font-size:25px;background:#CCD9FF;padding-top:0px;padding-bottom:1px;} .top_items{font-size:15px;} .holder{width=100%;} .bookHolder{width=100%;border-bottom-width: 1px;border-bottom-style:solid;border-bottom-color: #999;padding:8px;display: block;cursor: pointer;} a.nounderline:link {text-decoration: none;}.nounderline:visited {text-decoration: none;color: #0000CC;} .button {background:#E5ECFF;font-size:23px;padding:15px;border: 1px solid #000;	width: 70%;-moz-border-radius: 15px;border-radius: 15px} .advanceSearchButton{width:100%;text-align:center;background:#E5ECFF;color: #0000CC;padding:3px;} .advanceSearch{cursor: pointer;text-align:center;background:white;width=100%;border-bottom-width: 4px;border-bottom-style:solid;border-bottom-color: #E5ECFF;display:none;}--!></style></head>"+
		"<body><div class=\"top_bar\"><center>Libarae<br/>"+
		"<div class=\"top_items\"><a class=\"nounderline\" href=\"featured.html\">Featured</a> | <a class=\"nounderline\" href=\"search.html\">Library</a> | <a class=\"nounderline\" href=\"messages.html?mMailPageNumber=0\">Messages</a> | <a class=\"nounderline\" href=\"logout.html\">Logout</a>" +
		"<form name=\"input\" action=\"search.html\" method=\"get\"><input type=\"text\" name=\"mOmniSearch\" value=\""+search+"\" /> &nbsp; <input type=\"submit\" value=\"Search\" /></form></div>"+
		"</center></div>";
	}
	
	public static String HTMLDefultHeader(){
		return "<html><head><title>Libarae</title><style TYPE=\"text/css\"><!-- html,body{margin:0px;padding:0px;} .top_bar{width=100%;font-size:25px;background:#CCD9FF;padding:4px;} .holder{width=100%;} a.nounderline:link {text-decoration: none;}.nounderline:visited {text-decoration: none;color: #0000CC;} --!></style>"+
		"<meta name=\"viewport\" content=\"width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0\"/><meta name=\"format-detection\" content=\"telephone=no\"/></head>"+
		"<body><div class=\"top_bar\" ><center>Libarae</center></div>";
	}
	
	/**
	 * Short hand access to {@link URLEncoder#encode(String, String)} with the correct encoding
	 * @param toEncode
	 * @return the URL encoded form of the string
	 */
	@SuppressWarnings("deprecation")
	public static String encodeURL(String toEncode)
	{
		try {
			return URLEncoder.encode(toEncode, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			return URLEncoder.encode(toEncode);
		}
	}
}
